﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using OConf.Common;
using OConf.Entity;
using OConf.Model;
using OConf.Model.Common;
using OConf.Service;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace OConf.API.Filter
{
    /// <summary>
    /// 接口验签
    /// </summary>
    public class SignForApiAttribute : TypeFilterAttribute
    {
        public SignForApiAttribute() : base(typeof(SignForApiCoreAttribute))
        {
        }
    }

    public class SignForApiCoreAttribute : ActionFilterAttribute
    {
        private readonly ProjectInfoService _projectInfoService;
        public SignForApiCoreAttribute(IConfiguration configuration)
        {
            _projectInfoService = new ProjectInfoService(configuration);
        }

        public override void OnActionExecuting(ActionExecutingContext context)
		{
			try
			{
                var request = context.HttpContext.Request;
                string method = request.Method.ToString();

                //仅允许POST请求
                if (!method.ToUpper().Equals("POST"))
                {
                    ReturnData<object> result = new ReturnData<object>()
                    {
                        Code = (int)StatusCode.验签失败,
                        Msg = StatusCode.验签失败.ToString(),
                        Data = null
                    };
                    context.Result = new OkObjectResult(result);
                    return;
                }

                //获取接口请求参数
                string requestBody = string.Empty;
                if (request.ContentType.ToLower().Contains("application/json"))
                {
                    request.EnableBuffering();
                    request.Body.Position = 0L;
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        request.Body.CopyToAsync(memoryStream).Wait();
                        byte[] bytes = memoryStream.ToArray();
                        requestBody = Encoding.UTF8.GetString(bytes);
                    };
                }
                if (string.IsNullOrEmpty(requestBody))
                {
                    ReturnData<object> result = new ReturnData<object>()
                    {
                        Code = (int)StatusCode.验签失败,
                        Msg = StatusCode.验签失败.ToString(),
                        Data = null
                    };
                    context.Result = new OkObjectResult(result);
                    return;
                }

                SortedDictionary<string, object> dic = JsonConvert.DeserializeObject<SortedDictionary<string, object>>(requestBody);
                if (!dic.Any(w => w.Key == "ProgramName"))
                {
                    ReturnData<object> result = new ReturnData<object>()
                    {
                        Code = (int)StatusCode.验签失败,
                        Msg = StatusCode.验签失败.ToString(),
                        Data = null
                    };
                    context.Result = new OkObjectResult(result);
                    return;
                }

                ProjectInfoEntity projectInfo = _projectInfoService.FindEnityByProgramName(dic["ProgramName"].ToString());
                if (projectInfo == null || projectInfo.IsDelete)
                {
                    ReturnData<object> result = new ReturnData<object>()
                    {
                        Code = (int)StatusCode.验签失败,
                        Msg = StatusCode.验签失败.ToString(),
                        Data = null
                    };
                    context.Result = new OkObjectResult(result);
                    return;
                }

                if (!projectInfo.IsProtect)
                {
                    return;
                }

                if (!dic.Any(w => w.Key == "Sign"))
                {
                    ReturnData<object> result = new ReturnData<object>()
                    {
                        Code = (int)StatusCode.验签失败,
                        Msg = StatusCode.验签失败.ToString(),
                        Data = null
                    };
                    context.Result = new OkObjectResult(result);
                    return;
                }

                SortedDictionary<string, object> dic1 = new SortedDictionary<string, object>();
                dic1.Add("Key", projectInfo.SecretKey);
                foreach (var item in dic)
                {
                    if (item.Key == "Sign")
                    {
                        continue;
                    }
                    dic1.TryAdd(item.Key, item.Value);
                }
                string sign = JsonConvert.SerializeObject(dic1).MD5Encrypt();
                if (sign != dic["Sign"].ToString())
                {
                    ReturnData<object> result = new ReturnData<object>()
                    {
                        Code = (int)StatusCode.验签失败,
                        Msg = StatusCode.验签失败.ToString(),
                        Data = null
                    };
                    context.Result = new OkObjectResult(result);
                    return;
                }
            }
			catch (Exception ex)
			{
				Log4NetHelper.WriteExceptionLog("后端接口验证签名异常", ex);
                ReturnData<object> result = ReturnDataHelper<object>.Exception("系统异常");
                context.Result = new OkObjectResult(result);
                return;
            }
        }
    }
}
